#include "hexstringconvert.h"

int hexstringconvert::bytesreverse(unsigned char *io_data, int length)
{
	int index = 0;
	unsigned char temp = 0;

	if (NULL == io_data || 0 == length)
	{
		std::cout << "parameter is invaild!!!" << std::endl;
		return -1;
	}

	for (index = 0; index < length / 2; index++)
	{
		temp = io_data[index];
		io_data[index] = io_data[length - index - 1];
		io_data[length - index - 1] = temp;
	}
	return 0;
}

int hexstringconvert::string2hex(char* string, int i_length, unsigned char *hex, int *o_length)
{
	int index = 0;
	unsigned char tmp = 0;

	*o_length = 0;
	if (i_length % 2)
	{
		std::cout << "string format is not correct!!" << std::endl;
		return -1;
	}

	for (index = 0; index < i_length / 2; index++)
	{
		if (string[index * 2] >= '0' && string[index * 2] <= '9')
		{
			hex[index] = (string[index * 2] - '0') << 4;
		}
		else if (string[index * 2] >= 'a' && string[index * 2] <= 'z')
		{
			hex[index] = (string[index * 2] - 'a' + 0x0a) << 4;
		}
		else if (string[index * 2] >= 'A' && string[index * 2] <= 'Z')
		{
			hex[index] = (string[index * 2] - 'A' + 0x0a) << 4;
		}
		else
		{
			std::cout << "Need to conver string is not hex string!!!" << std::endl;
			return -1;
		}

		if (string[index * 2 + 1] >= '0' && string[index * 2 + 1] <= '9')
		{
			hex[index] += string[index * 2 + 1] - '0';
		}
		else if (string[index * 2 + 1] >= 'a' && string[index * 2 + 1] <= 'z')
		{
			hex[index] += string[index * 2 + 1] - 'a' + 0x0a;
		}
		else if (string[index * 2 + 1] >= 'A' && string[index * 2 + 1] <= 'Z')
		{
			hex[index] += string[index * 2 + 1] - 'A' + 0x0a;
		}
		else
		{
			std::cout << "Need to conver string is not hex string!!!" << std::endl;
			return -1;
		}
		tmp = hex[index];
	}
	*o_length = i_length / 2;
	return 0;
}

int hexstringconvert::stringfile2hexfile(const char *stringfilepath, const char *hexfilepath)
{
	if (NULL == hexfilepath || NULL == stringfilepath)
	{
		std::cout << "Parameter input error!!!" << "hexfilepath: " << hexfilepath << "stringfilepath" << stringfilepath << std::endl;
		return -1;
	}

	std::string inFileName = stringfilepath;
	std::string outFileName = hexfilepath;

	std::ifstream infile(inFileName.c_str());
	if (!infile.is_open())
	{
		std::cout << "File " << inFileName << " open failed!" << std::endl;
		return -1;
	}

	infile.seekg(0, infile.end);
	std::ios::pos_type srcSize = infile.tellg();
	infile.seekg(0);
	char *data = new char[srcSize];
	if (NULL == data)
	{
		std::cout << "data Memory allocate failed!!" << std::endl;
		infile.close();
		return -1;
	}

	int objSize = srcSize/2 + 1;
	unsigned char *hexdata = new unsigned char[objSize];
	if (NULL == hexdata)
	{
		std::cout << "hexdata Memory alloce failed!!" << std::endl;
		delete data;
		infile.close();
		return -1;
	}

	infile.read((char*)data, srcSize);
	memset(hexdata, 0, sizeof(hexdata));
	int result = this->string2hex(data, srcSize, hexdata, &objSize);
	delete data;
	infile.close();
	if (0 != result)
	{
		delete hexdata;
		std::cout << "string to hex failed!!!" << std::endl;
		return -1;
	}
	
	std::ofstream outfile(outFileName.c_str(), std::ios::trunc | std::ios::binary | std::ios::out);
	if (!outfile.is_open())
	{
		delete hexdata;
		std::cout << "File " << outFileName << " open failed!" << std::endl;
		return -1;
	}
	outfile.write((const char*)hexdata, objSize);
	delete hexdata;
	outfile.close();

	return 0;
}

int hexstringconvert::bytesfilereverse(const char *hexfilepath, const char *stringfilepath)
{
	if (NULL == hexfilepath || NULL == stringfilepath)
	{
		std::cout << "Parameter input error!!!" << "hexfilepath: " << hexfilepath << "stringfilepath" << stringfilepath << std::endl;
		return -1;
	}

	std::string inFileName = hexfilepath;
	std::string outFileName = stringfilepath;

	std::ifstream infile(inFileName.c_str(), std::ios::binary);
	if (!infile.is_open())
	{
		std::cout << "File " << inFileName << " open failed!" << std::endl;
		return -1;
	}

	infile.seekg(0, infile.end);
	std::ios::pos_type srcSize = infile.tellg();
	infile.seekg(0);
	unsigned char *data = new unsigned char[srcSize];
	if (NULL == data)
	{
		std::cout << "data Memory allocate failed!!" << std::endl;
		infile.close();
		return -1;
	}

	infile.read((char*)data, srcSize);
	int result = this->bytesreverse(data, srcSize);
	infile.close();
	if (0 != result)
	{
		std::cout << "string to hex failed!!!" << std::endl;
		return -1;
	}

	std::ofstream outfile(outFileName.c_str(), std::ios::trunc | std::ios::binary | std::ios::out);
	if (!outfile.is_open())
	{
		delete data;
		std::cout << "File " << outFileName << " open failed!" << std::endl;
		return -1;
	}
	outfile.write((const char*)data, srcSize);
	delete data;
	outfile.close();

	return 0;
}